/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine - graphics/context
// Copyright (c) 2015.  All Rights Reserved
//
// File:		AERenderContext.h
// Author:		Gianluca Belardelli
// Date:		10/06/2014
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AERENDERCONTEXT_H_
#define _AERENDERCONTEXT_H_

typedef AESmartPtr<AEContextViewProperties> AEContextViewPropertiesPtr;

/// \brief Classe per la gestione del Render Context.<br>
/// La classe permette di creare diverse istanze RenderContext con impostazioni individuali ( come ad
/// esempio il FOV, la viewport, la Camera e il Render Target ) e di renderizzarli indipendentemente
/// l'uno dall'altro.
/// I Render Context permettono anche di eseguire il rendering sulle Texture renderizzabili
/// impostate come Render Target, opzione che di solito viene utilizzata per il rendering
/// degli Shadow Buffer e degli effetti di post-processing.<br>
/// Ogni Render Context pu&ograve; avere un Render Loop individuale. Esiste un Render Context
/// permanente che viene creato durante l'inizializzazione dell'engine e distrutto durante
/// lo shutdown. Questo Render Context ha impostato il back buffer come Render Target e il
/// depth stencil target &egrave; corrisponde al buffer di depth stencil creato durante
/// l'inizializzazione della device ( AEBaseVideoDevice::InitializeScreen ).
class AERenderContext : public AEReferencedObject
{
	friend class AERenderContextContainer;
// Members
protected:
	static AERenderContext *m_lpCurrentContext;
	static AERenderContext *m_lpMainContext;

	AEFLOAT32		m_fPriority;	/// \internal Valore di priorit&agrave;

	AECamera		*m_lpContextCamera;	/// \internal Puntatore all'oggetto AECamera.
	AERenderLoopI	*m_lpRenderLoop;	/// \internal Puntatore all'oggetto AERenderLoopI.

	char			*m_lpContextName;	/// \internal Nome interno del Context.

	AEBOOL32		m_bInverseZViewport;
	AEBOOL32		m_bRenderingEnabled;
	AEBOOL32		m_bRecentlyRendered;
	AEBOOL32		m_bIgnoreWireframe;
	AEBOOL32		m_bRendersIntoBackBuffer;

	AEINT32			m_nRenderFlags;		/// \internal Flag di renderizzazione
	AEINT32			m_nShaderFlags;

	AEINT32			m_nSize[2];
	AEINT32			m_nViewportPos[2];
	AEINT32			m_nViewportSize[2];
	AEFLOAT32		m_fFOV[2];
	AEFLOAT32		m_fViewportZRange[2];
	AEFLOAT32		m_fLODCorrection;
	AEFLOAT32		m_fCustomLODScaling;

	AETexturePtr	m_spRenderTargets[AE_MAX_NUM_RENDERTARGETS];
	AEContextViewPropertiesPtr	m_spViewProps;

#if defined(AE_OPENGL) || defined(AE_OPENGLES2) || defined(AEOPENGLES3)
	AEUINT32		m_uiColorSurface[AE_MAX_NUM_RENDERTARGETS];
	AEUINT32		m_uiDepthStencilSurface;
	AEBOOL32		m_bUseStencil;
	static AEBOOL32 ms_bMultisamplingSupported;
	AEUINT32		m_uiFrameBufferObject;
#endif
// Methods
private:
	void _init( void );

public:
	/** @name Costruttori / Distruttore */
	/// @{
	/// \brief Costruttore di default.
	/// Un render context inizializzato senza parametri non pu&ograve; essere utilizzato per il rendering.
	/// E' necessario fornire almeno una Camera e un RenderTarget.
	AE_DLLIMPEXP AERenderContext( void );

	/// \brief Costruttore della classe AERenderContext.
	/// Questo costruttore prende in input tutti i parametri necessari per creare un RenderContext utilizzabile
	/// immediatamente per il rendering.
	/// \param lpCamera Puntatore all'oggetto AECamera utilizzato in questo RenderContext.
	/// \param fFovX Campo visivo (FOV) in direzione orizzontale espresso in gradi.
	/// \param fFovY Campo visivo (FOV) in direzione verticale espresso in gradi.
	/// \param nWidth Larghezza del RenderContext espressa in pixel.
	/// \param nHeight Altezza del RenderContext espressa in pixel.
	/// \param fNearClip Distanza del piano Near Clip espressa in Unit.
	/// \param fFarClip Distanza del piano Far Clip espressa in Unit.
	/// \param nRenderFlags Flags di renderizzazione utilizzati nel RenderContext. \sa AERenderContextFlags
	AE_DLLIMPEXP AERenderContext( const AECamera *lpCamera, AEFLOAT32 fFovX, AEFLOAT32 fFovY, AEINT32 nWidth, AEINT32 nHeight, AEFLOAT32 fNearClip, AEFLOAT32 fFarClip, AEINT32 nRenderFlags = 0 );

	/// \brief Distruttore
	AE_DLLIMPEXP virtual ~AERenderContext( void );

	/// @}
	/** @name Impostazioni */
	/// \brief Ritorna una stringa contenente il nome di questo Render Context.
	/// Metodo utilizzato principalmente in Debug.
	const char *GetContextName( void ) const;

	/// \brief Metodo che consente di impostare il nome di questo Render Context.
	/// \param lpNewString Puntatore alla stringa contenente il nome del Render Context.
	void SetContextName( const char *lpNewString );

	/// \brief Metodo che permette di impostare l'oggetto AECamera.
	/// Se una Camera esiste gi&agrave; viene sostituita da quella nuova.
	/// \param Puntatore ad un oggetto di tipo AECamera.
	AE_DLLIMPEXP void SetCamera( const AECamera *lpCamera );

	/// \brief Ritorna la camera attualmente utilizzata.
	/// \return Puntatore ad un oggetto di tipo AECamera.
	AE_DLLIMPEXP AECamera *GetCamera( void ) const;

	/// \brief Esegue il RenderLoop associato con questo Render Context.
	AE_DLLIMPEXP virtual void Execute( void );
	
	/// \brief Attiva questo Render Context.
	/// Una volta attivato il Render Context tutte le operazioni di rendering vengono eseguite su
	/// di esso.
	AE_DLLIMPEXP void Activate( void );

	/// @}
	/** @name Propriet&agrave; della Viewport */
	/// @{
	/// \brief Ritorna la dimensione della viewport impostata per questo RenderContext.
	/// \param nWidth [Out] Larghezza in pixel della viewport.
	/// \param nHeight [Out] Altezza in pixel della viewport.
	AE_DLLIMPEXP void GetViewportSize( AEINT32 &nWidth, AEINT32 &nHeight ) const;

	/// \brief Specifica le impostazioni della viewport da utilizzare con questo RenderContext.
	/// Per default la viewport sar&agrave; impostata per prendere tutta l'ampiezza del
	/// RenderTarget impostata con SetSize ( quando il rendering &egrave; effettuato nel
	/// back buffer), oppure &egrave; impostata con la dimensione della texture utilizzata
	/// come RenderTarget.<br> Questo metodo pu&ograve; essere utilizzato se si vuole
	/// renderizzare solo una parte del RenderTarget.
	/// \param nPosX Coordinata X, in pixels, dell'angolo superiore destro della viewport.
	/// \param nPosY Coordinata Y, in pixels, dell'angolo superiore destro della viewport.
	/// \param nWidth Larghezza, in pixels, della viewport.
	/// \param nHeight Altezza, in pixels, della viewport.
	/// \param fZMin Valore Near Z della viewport( nel range 0.0 - 1.0 ).
	/// \param fZMax Valore Far Z della viewport( nel range 0.0 - 1.0 ).
	AE_DLLIMPEXP void SetViewport( AEINT32 nPosX, AEINT32 nPosY, AEINT32 nWidth, AEINT32 nHeight, AEFLOAT32 fZMin, AEFLOAT32 fZMax );

	/// \brief Ritorna le informazioni sulla viewport utilizzata da questo RenderContext.
	/// \param nPosX [Out] Coordinata X, in pixels, dell'angolo superiore destro della viewport.
	/// \param nPosY [Out] Coordinata Y, in pixels, dell'angolo superiore destro della viewport.
	/// \param nWidth [Out] Larghezza, in pixels, della viewport.
	/// \param nHeight [Out] Altezza, in pixels, della viewport.
	/// \param fNear [Out] Valore Near Z della viewport( nel range 0.0 - 1.0 ).
	/// \param fFar [Out] Valore Far Z della viewport( nel range 0.0 - 1.0 ).
	AE_DLLIMPEXP void GetViewport( AEINT32 &nPosX, AEINT32 &nPosY, AEINT32 &nWidth, AEINT32 &nHeight, AEFLOAT32 &fNear, AEFLOAT32 &fFar ) const;

	/// \brief Imposta il Field Of View orizzontale o verticale per questo Render Context.
	/// Se il valore &egrave; 0.0f, il FOV verr&agrave; calcolato automaticamente in base agli altri
	/// dati disponibili e all'Aspect Ration corrente del display video.
	/// \param fFovX Field Of View orizzontale in gradi.
	/// \param fFovY Field Of View verticale in gradi.
	AE_DLLIMPEXP void SetFOV( AEFLOAT32 fFovX, AEFLOAT32 fFovY = 0.0f );

	/// \brief Ritorna il Field Of View orizzontale e verticale per questo Render Context.
	/// \param fFovX [Out] Field Of View orizzontale in gradi.
	/// \param fFovY [Out] Field Of View verticale in gradi.
	AE_DLLIMPEXP void GetFOV( AEFLOAT32 &fFovX, AEFLOAT32 &fFovY ) const;

	/// \brief  Imposta i valori di clipping Near e Far di questo Render Context.
	/// \param fNearClipDist Valore di Near clip distance per questo Render Context.
	/// \param fFarClipDist Valore di Far clip distance per questo Render Context.
	AE_DLLIMPEXP void SetClipPlanes( AEFLOAT32 fNearClipDist, AEFLOAT32 fFarClipDist );

	/// \brief Ritorna i valori di clipping Near e Far di questo Render Context.
	/// \param fNearClipDist Referenza che riceve il valore corrente di Near 
	/// clip distance per questo Render Context.
	/// \param fFarClipDist Referenza che riceve il valore corrente di Far 
	/// clip distance per questo Render Context.
	AE_DLLIMPEXP void GetClipPlanes( AEFLOAT32 &fNearClipDist, AEFLOAT32 &fFarClipDist ) const;

	/// @}
	/** @name Metodi statici per accesso globale */
	/// @{
	/// \brief Ritorna un puntatore al Render Context attivo.
	AE_DLLIMPEXP static AERenderContext *GetCurrentContext( void );

	/// \brief Ritorna un puntatore al Render Context principale dell'engine.
	/// Il Render Context principale non dovrebbe mai essere cancellato automaticamente,
	/// sar&agrave; cura dell'engine occuparsene.
	AE_DLLIMPEXP static AERenderContext *GetMainRenderContext( void );

	/// @}
	/** @name Propriet&agrave; del Render e Render Target */
	/// @{
	/// \brief Ritorna AETRUE se questo Render Context renderizza nel back-buffer.
	AE_DLLIMPEXP AEBOOL32 IsRenderIntoBackBuffer( void ) const;
	
	/// \brief Il metodo ritorna la texture del Render Target di questo Render Context.
	/// Invocare questo metodo sul Render Context principale ritorner&agrave; AENULL.
	/// Per determinare se l'oggetto ritornato &egrave una CubeMap, una Texture 2D o un'array
	/// di Texture 2D, &egrave; sufficente invocare AETexture::GetTextureType, oppure AETexture::IsCubemap o
	/// AETexture::IsTexture2DArray, una volta ottenuto il tipo di Texture l'oggetto ritornato pu&ograve;
	/// essere castato nell'opportuna classe ( AERenderableTexture, AERenderableCubemap ecc. ).
	/// \param nRenderTargetIndex Indice del Render Target da ritornare ( il default &egrave; 0 ).
	/// \param lpFaceOrIndex Se il parametro non &egrave; AENULL e il Render Target &egrave; una Cube Map
	/// allora conterr&agrave; l'indice della faccia del cubo impostata come Render Target.<br>
	/// Se il parametro non &egrave; AENULL e il Render Target &egrave; un array di Texture 2D
	/// allora conterr&agrave; l'indice dell'array di Texture impostato come Render Target.
	/// \return Puntatore ad un oggetto di tipo AETexture. Pu&ograve; essere AENULL.
	AE_DLLIMPEXP AETexture *GetRenderTarget( AEINT32 nRenderTargetIndex = 0, AEINT32 *lpFaceOrIndex = AENULL ) const;
	/*
	/// \brief Function that returns the depth stencil target of this context
	/// The depth stencil target can be set using the SetDepthStencilTarget method.
	/// Note that if this function returns NULL, this only means that there is no renderable texture
	/// set as a depth stencil target for this context. If e.g.
	/// VisRenderContext_cl::SetDepthStencilSurface has been used to directly set a DirectX surface
	/// as depth stencil target, this method will return NULL. Similarly, calling this method on the
	/// main render context will also return NULL.
	/// In order to determine whether the returned object is a renderable cube map, a renderable 2D
	/// texture, or a renderable 2D texture array, simply check the type of the returned
	/// VTextureObject (GetTextureType), or call IsCubemap() and IsTexture2DArray() or it. You may
	/// then cast the object to the respective target type (e.g. VisRenderableCubemap_cl,
	/// VisRenderableTexture_cl).
	/// \param pFaceOrIndex
	///   If not NULL and the depth stencil texture is a cube map, this will contain the face index
	///   of the cube map which is set as the depth stencil target for this context. If not NULL and
	///   the depth stencil target is a 2D texture array, this will contain the array index of the
	///   texture array which is set as the depth stencil target for this context. In DirectX10/11, if
	///   the depth stencil target is a cube map or array texture and this value is -1, this means
	///   that the depth stencil target is not a specific face or slice of the cubemap/array texture,
	///   but it is the complete texture object. In this case, the face or array index to render to
	///   can be chosen in the geometry shader.
	/// \return
	///   VTextureObject *: NULL or the offscreen render target (renderable texture)
	//AE_DLLIMPEXP VTextureObject *GetDepthStencilTarget( AEINT32 *lpFaceOrIndex = 0L ) const;
	*/

	/// \brief Metodo per impostare i Render Target per questo Render Context.
	/// Il metodo imposta solo il Render Target primario, il depth stencil pu&ograve; essere
	/// impostato tramite AERenderContext::SetDepthStencilTarget.<br>
	/// La funzione si occupa di correggere anche i valori della viewport basandosi sulle
	/// dimensioni del Render Target.
	/// Il numero di Render Target simultanei supportato dipende dalla configurazione
	/// della piattaforma.
	/// Per disabilitare uno specifico Render Target &egrave; ammesso specificare AENULL come parametro
	/// \c lpTexObject, ma bisogna tenere a mente che su DirectX9 non &egrave; possibile impostare
	/// a NULL il Render Target con indice 0.
	/// \note Se vengono utilizzati pi&ugrave; Render Target essi \b devono avere le stesse dimensioni
	/// e lo stesso formato.
	/// \param nRenderTargetIndex Indice del Render Target da impostare.
	/// \param lpTexObject Un'oggetto di tipo AERenderableTexture o AENULL.
	/// \return  AETRUE se il Render Target &egrave stato impostato con successo, altrimenti AEFALSE.
	AE_DLLIMPEXP AEBOOL32 SetRenderTarget( AEINT32 nRenderTargetIndex, const AERenderableTexture *lpTexObject );

	/// \brief Function to set the depth-stencil target for this context
	/// Note that the depths stencil target usually has to have the same size as the color buffer
	/// that is being rendered to.
	/// Note that the passed VisRenderableTexture_cl has to be in a valid depth-stencil target format
	/// (the exact requirements depend on the target platform, hardware, and drivers).
	/// It is valid to specify NULL for pTexObject.
	/// \param pTexObject Has to be either NULL or a renderable texture object.
	/// \return AEBOOL32: true if setting the render target was successful
	AE_DLLIMPEXP AEBOOL32 SetDepthStencilTarget( const AERenderableTexture *lpTexObject );

	/// \brief Ritorna il numero di Render Target attivi per questo Render Context.
	AE_DLLIMPEXP AEUINT32 GetNumRenderTargets( void ) const;

	/// \brief Abilita o disabilita il rendering per questo Render Context.
	/// \param bStatus AETRUE per abilitare il rendering, AEFALSE per disabilitarlo.
	AE_DLLIMPEXP void SetRenderingEnabled( AEBOOL32 bStatus );

	/// \brief Ritorna AETRUE se il rendering &egrave; abilitato per questo Render Context,
	/// altrimenti AEFALSE.
	AE_DLLIMPEXP AEBOOL32 IsRenderingEnabled( void ) const;

	/// @}
	/** @name Render Flags */
	/// @{
	/// \brief Il metodo imposta i Render Flag per questo Context.
	/// E' consigliato di non richiamare il metodo all'interno del RenderLoop.
	/// \param nFlags Combinazione di Render Flag.
	/// \sa AERenderContextFlags.
	AE_DLLIMPEXP void SetRenderFlags( AEINT32 nFlags );

	/// \brief Ritorna i Render Flags impostati per questo Render Context.
	AE_FORCEINLINE AEINT32 GetRenderFlags( void ) const;

	/// @}
	/** @name Render Loop */
	/// @{
	/// \brief Imposta il RenderLoop per questo Render Context.
	/// I Render Context possono avere una loro implementazione per il Render Loop che
	/// pu&ograve; essere impostata con questo metodo.<br>
	/// Per default i Render Context utilizzano il Render Loop di default fornito con l'engine.
	/// \param lpRenderLoop Puntatore ad un oggetto di tipo AERenderLoopI.
	AE_DLLIMPEXP void SetRenderLoop( AERenderLoopI *lpRenderLoop );

	/// \brief Ritorna il puntatore all'oggetto AERenderLoopI impostato per
	/// questo Render Context.
	AE_DLLIMPEXP AERenderLoopI *GetRenderLoop( void ) const;
	
	/// \brief Imposta la priorit&agrave; di questo Render Context.
	/// La priorit&agrave; pu&ograve; essere utilizzata per impostare uno specifico
	/// ordine di rendering dei Render Context che dipendono uno dall'altro.
	/// Ad esempio un Render Context, utilizzato per renderizzare le ombre, ha una priorit&agrave; pi&ugrave;
	/// bassa del Render Context principale perch&egrave;, quest'ultimo, utilizza il risultato &egrave;
	/// del precedente. Quindi le priorit&agrave; pi&ugrave; basse sono quelle renderizzate per prime.
	/// La priorit&agrave; di default &egrave; 0.0.
	/// \param fPriority Valore di priorit&agrave;.
	AE_DLLIMPEXP void SetPriority( AEFLOAT32 fPriority );

	/// \brief Ritorna la priorit&agrave; di questo Render Context.
	AE_FORCEINLINE AEFLOAT32 GetPriority( void ) const;

	/*
	/// \brief Computes and returns the view frustum generated using the camera position and orientation
	///   and the render context's field of view/clip plane settings.
	/// Every call to this function recomputes the frustum. Check whether using
	/// VisionVisibilityCollector_cl::GetBaseFrustum may be an alternative for you.
	///  \param viewFrustum
	///   Empty frustum object to be filled with data in this function.
	//AE_DLLIMPEXP void GetViewFrustum( VisFrustum_cl &viewFrustum ) const;
	*/

	/// @}
	/** @name Matrici */
	/// @{
	/// \brief Ritorna una referenza alla matrice di proiezione correntemente utilizzata.
	/// La matrice di proiezione &egrave; generata dai valori correnti della Frustum, del piano
	/// di clipping e della FOV, e include il flipping della coordinata y sulle piattaforme
	/// OpenGL quando il rendering &egrave; effettuato su una texture.
	/// Per recuperare la matrice originale senza la correzione sulla coordinata y utilizzare
	/// GetViewProperties()->GetProjectionMatrix( AEClipSpaceYRange::MinusOneToOne ).
	/// \return Una matrice di proiezione 4x4 di tipo AEMatrix4f.
	/// \sa AERenderContext::SetFOV
	/// \sa AERenderContext::SetClipPlanes
	/// \sa AEContextCamera::GetInverseEyeMatrix
	AE_DLLIMPEXP const AEMatrix4f &GetProjectionMatrix( void ) const;

	/// \brief Metodo che permette di impostare una matrice di proiezione custom per
	/// questo Render Context.<br>
	/// Il metodo pu&ograve; risultare utile per creare Clip Planes personalizzati, ad esempio
	/// per il rendering dell'acqua.
	/// La matrice di proiezione custom sar&agrave; utilizzata solo per il rendering e non
	/// per la determinazione della visibilit&agrave; la quale, sar&agrave; sempre calcolata
	/// dai valori di FOV e dai Clip Planes.
	/// Per reimpostare la matrice di proiezione di default basta passare un puntatore AENULL
	/// al parametro \c lpMatrix.<br>
	/// Se il metodo &egrave; invocato passando una matrice valida, il tipo di proiezione
	/// &egrave; automaticamente impostato a AEPROJECTIONTYPE_CUSTOM.
	/// \param lpMatrix Puntatore alla nuova matrice di proiezione. La matrice verr&agrave;
	/// copiata invece di essere referenziata. Pu&ograve; essere utilizzato AENULL per
	/// ripristinare la matrice di proiezione di default.
	/// \param bAutoFrustum Se il valore &egrave; AETRUE, la Frustum View sar&agrave; calcolata
	/// automaticamente dalla matrice di proiezione.
	/// \sa AERenderContext::SetFOV
	/// \sa AERenderContext::SetClipPlanes
	/// \sa AEContextCamera::GetInverseEyeMatrix
	AE_DLLIMPEXP void SetCustomProjectionMatrix( const AEMatrix4f *lpMatrix, AEBOOL32 bAutoFrustum = AETRUE );

	/// \brief Imposta una nuova matrice di proiezione.
	/// Se &egrave; di tipo AEPROJECTIONTYPE_PERSPECTIVE o AEPROJECTIONTYPE_ORTHOGRAPHIC
	/// allora il Render Context si occupa di creare automaticamente la matrice di proiezione appropriata.<br>
	/// Per default ad ogni nuovo Render Context &egrave; associata una matrice di
	/// tipo AEPROJECTIONTYPE_PERSPECTIVE.
	/// \param eType Pu&ograve; assumere uno dei seguenti valori:
	///   \li \b AEPROJECTIONTYPE_PERSPECTIVE: Una matrice di proiezione prospettica &egrave; definita
	///       utilizzando i valori di Clip Planes e FOV.
	///   \li \b AEPROJECTIONTYPE_ORTHOGRAPHIC: Una matrice di proiezione ortografica &egrave; definita
	///       utilizzando le dimensioni di questo Render Context.
	///   \li \b AEPROJECTIONTYPE_CUSTOM: La matrice di proiezione &egrave; custom e deve essere impostata
	///       tramite AERenderContext::SetCustomProjectionMatrix.
	/// \sa AERenderContext::SetFOV
	/// \sa AERenderContext::SetClipPlanes
	/// \sa AEContextCamera::GetInverseEyeMatrix
	AE_FORCEINLINE void SetProjectionType( AEProjectionType eType );

	/// \brief Ritorna il tipo di proiezione impostata per questo Render Context.
	/// \sa AERenderContext::SetProjectionType
	AE_FORCEINLINE AEProjectionType GetProjectionType( void );

	/// \brief
	///   This function must be called when the projection matrix has changed within the render loop and the changes should take place immediately.
	/// 
	/// It re-builds the projection matrix and re-uploads the shader constants (projection and modelview projection). This is necessary when the projection matrix
	/// changes inside the execution of a renderloop through calls of SetFOV or SetClipPlanes. It is not necessary to call this function
	/// in normal cases where changing projection settings should be applied in the next frame. Accordingly this function asserts when called
	/// from outside a render loop.
	AE_DLLIMPEXP void ApplyProjectionMatrixChanges( void );

	/// \brief Imposta le dimensioni ortografiche per questo Render Context.<br>
	/// Possono essere impostate come la dimensione dello schermo per ottenere un mapping 1:1.
	/// Il metodo ha i suoi effetti solo se la modalit&agrave; di proiezione &egrave; AEPROJECTIONTYPE_ORTHOGRAPHIC.
	/// \param fWidth Valore della larghezza.
	/// \param fHeight Valore dell'altezza.
	AE_DLLIMPEXP void SetOrthographicSize( AEFLOAT32 fWidth, AEFLOAT32 fHeight );

	/// \brief Ritorna le dimensioni correnti della matrice ortografica.
	/// \param fWidth [Out] Referenza che conterr&agrave; il valore di larghezza.
	/// \param fHeight [Out] Referenza che conterr&agrave; il valore di altezza.
	AE_FORCEINLINE void GetOrthographicSize( AEFLOAT32 &fWidth, AEFLOAT32 &fHeight );

	/// \brief Metodo che consente di costruire una matrice 4x4 per il tipo di proiezione
	/// passata come parametro.
	/// \param refMatrix [Out] Referenza alla matrice da creare.
	/// \param eProjectionType Tipo di proiezione.
	AE_DLLIMPEXP void ComputeProjectionMatrix( AEMatrix4f &refMatrix, AEProjectionType eProjectionType ) const;
	/// @}
};

#include "AERenderContext.inl"

#endif // _AERENDERCONTEXT_H_
